package io.github.talelin.latticy.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.github.talelin.latticy.common.util.PageUtil;
import io.github.talelin.latticy.dto.rule.chargePlan.ChargePlanDTO;
import io.github.talelin.latticy.model.ChargeOmsUserDO;
import io.github.talelin.latticy.model.ChargePlanDO;
import io.github.talelin.latticy.mapper.ChargePlanMapper;
import io.github.talelin.latticy.model.ChargePlanItemDO;
import io.github.talelin.latticy.service.ChargeOmsUserService;
import io.github.talelin.latticy.service.ChargePlanItemService;
import io.github.talelin.latticy.service.ChargePlanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.github.talelin.latticy.vo.ChargePlanPageVO;
import io.github.talelin.latticy.vo.PageResponseVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 计费方案 服务实现类
 * </p>
 *
 * @author generator@wulongbo
 * @since 2022-08-23
 */
@Service
public class ChargePlanServiceImpl extends ServiceImpl<ChargePlanMapper, ChargePlanDO> implements ChargePlanService {

    @Autowired
    private ChargePlanItemService chargePlanItemService;

    @Autowired
    private ChargeOmsUserService chargeOmsUserService;


    @Transactional
    @Override
    public boolean addChargePlan(ChargePlanDTO dto) {
        boolean flag;
        // 1:添加计费方案
        ChargePlanDO chargePlanDO = new ChargePlanDO(dto.getName(), dto.getWarehousingAmount(), dto.getExWarehouseAmount(), dto.getReturnGoodsAmount());
        // 验证计费方案是否存在
        checkChargePlanName(chargePlanDO.getName(), null);
        flag = this.save(chargePlanDO);
        Assert.isTrue(flag, "18815");
        return addChargePlanDetails(dto, chargePlanDO);
    }

    /**
     * 添加计费方案相关子项及关联用户
     *
     * @param dto
     * @param chargePlanDO
     * @return
     */
    public boolean addChargePlanDetails(ChargePlanDTO dto, ChargePlanDO chargePlanDO) {
        boolean flag;
        //1:添加charge_plan_item
        List<ChargePlanItemDO> chargePlanItemDOList = dto.getChargeItemIds().parallelStream()
                .map(id -> new ChargePlanItemDO(chargePlanDO.getId(), id)).collect(Collectors.toList());
        flag = chargePlanItemService.saveBatch(chargePlanItemDOList);
        Assert.isTrue(flag, "18816");
        //2:添加charge_oms_user
        List<ChargeOmsUserDO> chargeOmsUserDOList = dto.getIds().parallelStream()
                .map(id -> new ChargeOmsUserDO(id, chargePlanDO.getId())).collect(Collectors.toList());
        flag = chargeOmsUserService.saveBatch(chargeOmsUserDOList);
        Assert.isTrue(flag, "18817");
        return flag;
    }

    @Transactional
    @Override
    public boolean updateChargePlan(Integer id,ChargePlanDTO dto) {
        boolean flag;
        //1.验证计费方案是否存在
        ChargePlanDO chargePlanDO = this.getById(id);
        Assert.notNull(chargePlanDO, "18819");
        //2.验证计费方案名称是否存在
        checkChargePlanName(dto.getName(), chargePlanDO.getName());
        chargePlanDO.setName(dto.getName());
        flag = this.updateById(chargePlanDO);
        Assert.isTrue(flag, "18824");
        //3.删除计费方案相关子项及关联用户,进行重新添加
        flag = deleteChargePlanDetails(id);
        Assert.isTrue(flag, "18821");
        //4.重新添加计费方案相关子项及关联用户
        flag = addChargePlanDetails(dto, chargePlanDO);
        Assert.isTrue(flag, "18816");
        return flag;
    }

    @Transactional
    @Override
    public boolean deleteChargePlan(Integer chargePlanId) {
        // 1:删除计费方案表
        boolean flag = this.baseMapper.deleteById(chargePlanId);
        Assert.isTrue(flag, "18820");
        // 2:删除计费方案相关子项及关联用户
        return deleteChargePlanDetails(chargePlanId);
    }

    /**
     * 删除计费方案相关子项及关联用户
     *
     * @param chargePlanId
     * @return
     */
    private boolean deleteChargePlanDetails(Integer chargePlanId) {
        // 1:删除方案关联计费项表
        boolean flag = chargePlanItemService.deleteByChargePlanId(chargePlanId);
        Assert.isTrue(flag, "18821");
        // 2:删除计费方案关联用户表
        flag = chargeOmsUserService.deleteByChargePlanId(chargePlanId);
        Assert.isTrue(flag, "18822");
        return flag;
    }

    @Override
    public ChargePlanPageVO getChargePlanById(Integer id) {
//        ChargePlanDO chargePlanDO = this.getById(id);
//        Assert.notNull(chargePlanDO, "18819");
//        //1.关联计费方案项集合
//        ChargePlanPageVO chargePlanDetailsVO = new ChargePlanPageVO();
//        BeanUtils.copyProperties(chargePlanDO, chargePlanDetailsVO);
//        List<ChargePlanItemsDTO> chargePlanItems = chargeItemService.getItemsByChargePlanById(id);
//        chargePlanDetailsVO.setChargePlanItems(chargePlanItems);
//        //2.关联用户id集合
//        LambdaQueryWrapper<ChargeOmsUserDO> wrapper = Wrappers.lambdaQuery();
//        wrapper.eq(ChargeOmsUserDO::getChargePlanId, id);
//        List<ChargeOmsUserDO> omsUserDOList = chargeOmsUserService.list(wrapper);
//        if (CollectionUtils.isNotEmpty(omsUserDOList)) {
//            List<Integer> omsUserIdList = omsUserDOList.parallelStream().map(ChargeOmsUserDO::getUserId).distinct().collect(Collectors.toList());
//            chargePlanDetailsVO.setOmsUserId(omsUserIdList);
//        }
//        return chargePlanDetailsVO;
        return null;
    }

    @Override
    public PageResponseVO<ChargePlanPageVO> getChargePlanPage(Integer page, Integer count, String name) {
//        LambdaQueryWrapper<ChargePlanDO> wrapper = Wrappers.lambdaQuery();
//        if (StringUtils.isNoneBlank(name)) {
//            wrapper.like(ChargePlanDO::getName, name);
//        }
//        IPage<ChargePlanDO> chargePlanPage = this.baseMapper.selectPage(new Page<>(page, count), wrapper);
//        IPage<ChargePlanVO> resultPage = PageHelpUtil.convertPage(chargePlanPage, ChargePlanVO.class);
//        return resultPage;
        List<ChargePlanPageVO> list = this.baseMapper.getChargePlanPage(page * count, count, name);
        IPage<ChargePlanPageVO> iPage = new Page<>(page, count);
        int totalRecords = this.baseMapper.getTotalByPlanName(name);
        iPage.setTotal(totalRecords);
        int totalPages = totalRecords % count == 0 ? totalRecords / count
                : totalRecords / count + 1;
        iPage.setPages(totalPages);
        return PageUtil.build(iPage, list);
    }

    /**
     * 验证计费方案是否存在
     *
     * @param newChargePlanName 更新计费方案名称
     * @param oldChargePlanName 原始计费方案名称
     */
    private void checkChargePlanName(String newChargePlanName, String oldChargePlanName) {
        LambdaQueryWrapper<ChargePlanDO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ChargePlanDO::getName, newChargePlanName);
        if (StringUtils.isNoneBlank(oldChargePlanName)) {
            wrapper.ne(ChargePlanDO::getName, oldChargePlanName);
        }
        int count = this.count(wrapper);
        Assert.isFalse(count > 0, "18818");
    }
}
